package com.jobs.producer2.config;


import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.listener.api.RabbitListenerErrorHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

@Slf4j
@Configuration
public class MqConfig {

    @Autowired
    private AmqpTemplate amqpTemplate;
    /**
     * 延迟交换机名称
     */
    public static final String DELAY_EXCHANGE_NAME="delay-exchange";
    /**
     * 延迟交换机的类型
     */
    public static final String DELAY_EXCHANGE_TYPE = "x-delayed-message";
    /**
     * 错误重试延迟
     */
    private static  Integer DELAY = 4;
    /**
     * 最大重试次数,2880次*30秒=24小时，也就是说，默认重试24小时
     */
    private static  Integer MAX_RETRY = 20;

//    @Value("${retry.max_retry}")
    public void setMaxRetry(Integer maxRetry){
        MAX_RETRY = maxRetry;
    }

//    @Value("${retry.delay}")
    public void setDelay(Integer delay){
        DELAY = delay;
    }

    // mq的异常处理器
    @Bean
    public RabbitListenerErrorHandler retryErrorHandler() {
        //  RabbitListenerErrorHandler errorHandler =
        return  (amqpMessage, message, exception) -> {
            log.error("message监听器出错了",exception);
            MessageProperties messageProperties = amqpMessage.getMessageProperties();
            Map<String, Object> headers = messageProperties.getHeaders();
            Integer xRetryCount = ((Integer) headers.get("retry-count"));
            //根据失败次数，决定是否继续发送到延迟队列
            if (xRetryCount == null) {
                xRetryCount = MAX_RETRY;
            }
            Integer retriedCount = (Integer) headers.get("retried-count");
            if (retriedCount == null) {
                retriedCount = 1;
            }
            log.info("已执行次数:{},最大重试次数:{}",retriedCount,xRetryCount);
            if(retriedCount < xRetryCount){
                log.info("已执行次数小于最大重试次数");
                retriedCount++;
                headers.put("retried-count",retriedCount);
                String routingKey = messageProperties.getConsumerQueue();
                messageProperties.setDelay(DELAY);
                log.info("延迟:{}毫秒", DELAY);
                log.info("路由key:{}",routingKey);
                amqpTemplate.send(DELAY_EXCHANGE_NAME, routingKey, amqpMessage);
                return null;
            }
            log.info("已执行次数达到最大重试次数了,不再进行重试");
            return null;
        };
    }
}

